<?php
namespace App\Api\Controllers\CmbcUnion;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

//require_once("demo/php_java.php");//引用LAJP提供的PHP脚本

class BaseController
{
    static $instance, $data;

//    const MIAN = 'http://test.umbpay.com.cn:12080/cashier/transV2/service.do';

    const MIAN = 'https://www.umbpay.cn/cashier/transV2/service.do';

   // const UPLOAD_IMG = 'http://test.umbpay.com.cn:12080/cmsmeraccess/public/imageUploadV2.do';

    const UPLOAD_IMG = 'https://www.umbpay.cn/cmsmeraccess/public/imageUploadV2.do';

//    const APPLY = 'http://test.umbpay.com.cn:12080/cmsmeraccess/transV2/service.do';

    const APPLY = 'https://www.umbpay.cn/cmsmeraccess/transV2/service.do';
    public static $RsaPrivateKeyFilePath;
    public static $RsaPrivateKeyFilePassword;
    public static $RsaPublicKeyFilePath;
    //以下为SM2证书信息
    //SM2签名私钥文件路径
    public static $SM2SignPrivateKeyFilePath;
    //SM2签名私钥密码
    public static $SM2SignPrivateKeyFilePassword;
    //SM2加密私钥文件路径
    public static $SM2EncPrivateKeyFilePath;
    //SM2加密私钥密码
    public static $SM2EncPrivateKeyFilePassword;
    //SM2验签公钥文件路径(平台提供)
    public static $SM2SignPublicKeyFilePath;
    //SM2加密公钥文件路径(平台提供)
    public static $SM2EncPublicKeyFilePath;

    public static function getInstance ()
    {
        if (! isset(self::$instance)) {
            self::$instance = new self();
        }

        self::$RsaPrivateKeyFilePath = app_path('Api/Controllers/CmbcUnion/cer/merchant.pfx');
        self::$RsaPrivateKeyFilePassword = 'umbpay';
        self::$RsaPublicKeyFilePath = app_path('Api/Controllers/CmbcUnion/cer/platform.cer');
        //以下为SM2证书信息
        self::$SM2SignPrivateKeyFilePath = app_path('Api/Controllers/CmbcUnion/cer/mechant_sign_sm2.sm2');
        self::$SM2SignPrivateKeyFilePassword = 'cmbc123';
        self::$SM2EncPrivateKeyFilePath = app_path('Api/Controllers/CmbcUnion/cer/mechant_enc_sm2.sm2');

        self::$SM2EncPrivateKeyFilePassword = 'cmbc123';
        self::$SM2SignPublicKeyFilePath = app_path('Api/Controllers/CmbcUnion/cer/platfrom_sign_sm2.cer');
        self::$SM2EncPublicKeyFilePath = app_path('Api/Controllers/CmbcUnion/cer/platfrom_enc_sm2.cer');


        return self::$instance;
    }

    public function params ($body, $head)
    {
        $dataParams = json_encode([
            'head' => [
                "mertrandate" => date('Ymd'),
                'mertrantime' => date('His'),
                'platmerid'   => $head['platmerid'], // 平台客户号码
                'trancode'    => $head['trancode'],  //'CAS008',//交易编码
                'tranflow'    => $head['tranflow'],  // 平台客户号码+订单号+随机数
            ],
            'body' => $body,
        ], JSON_UNESCAPED_UNICODE+JSON_FORCE_OBJECT);
        $dataParams = str_replace('\/', '/', $dataParams);

        $messageParams = [
            'data' => $dataParams,
            'sign' => self::createSign($dataParams), //签名
        ];
        $sysDataParams = json_encode(['message' => $messageParams], JSON_UNESCAPED_UNICODE+JSON_FORCE_OBJECT);

        $sysDataParams = str_replace('\/', '/', $sysDataParams);
        $sysDataString = self::Sm2Encrypt($sysDataParams);

        self::$data = [
            'formatType' => 'json',
            'cryptType'  => 'sm2',
            'signType'   => 'sm2',
            'data'       => $sysDataString,
        ];
        return $this;
    }

    public function uploadImg ($data, $trancode)
    {
        $dataParams = [
            'platmerid' => $data['platformId'],
            'trancode' => $trancode,
            'img'      => $data['last50'],
            'trantime' => date('YmdHis')
        ];

        $sysDataParams = json_encode([
            'data' => $dataParams,
            'sign' => self::createSign(json_encode($dataParams)), //签名
        ]);

        $sysDataString = self::Sm2Encrypt($sysDataParams);

        self::$data = [
            'formatType' => 'json',
            'cryptType'  => 'sm2',
            'signType'   => 'sm2',
            'imgs'       => $data['imgs'],
            'data'       => $sysDataString,
        ];
        return $this;
    }

    public static function  createSign ($data)
    {
//        $password = self::$SM2SignPrivateKeyFilePassword;
//        $SM2SignPrivateKeyFilePath = self::$SM2SignPrivateKeyFilePath;
//
//        $base64SourceString = base64_encode(str_replace(" ","+",$data));#str_replace(" ","+",$_GET['str'])
//        $signAlg = 'sm3WithSM2Encryption';
//
//
//        $signRet = lajp_call("cfca.sadk2.api.SignatureKitSm2::P7SignMessageSm2Detached",  $signAlg,$base64SourceString, $SM2SignPrivateKeyFilePath, $password);
//        $signArr = json_decode($signRet);
//        return $signArr->Base64SignatureString;
        $base64SourceString = base64_encode(str_replace(" ","+",$data));#str_replace(" ","+",$_GET['str'])
        $params = [
            'data'    => $base64SourceString,
            'prikey'  => '../mechant_sign_sm2.sm2',
            'signalg' => 'sm3WithSM2Encryption',
            'p12pwd'  => self::$SM2SignPrivateKeyFilePassword
        ];
        $signRet = self::getSign('http://cmbc_union.wftpay.cn/get_sign_data.php', $params);
        $signArr = json_decode($signRet);
        if (isset($signArr->Base64SignatureString)) {
            return $signArr->Base64SignatureString;
        }
        return '';
    }

    /**
     * 使用LAJP工具包SM2算法加密
     * @param  string $data 源字符串
     * @return 密文
     */
    public static function Sm2Encrypt($data)
    {
//        $sm2signAlg = 'SM4/ECB/PKCS7Padding';
//        $sm2base64CertData = file_get_contents(self::$SM2EncPublicKeyFilePath);
//        $sm2base64CertData = str_replace(['-----BEGIN CERTIFICATE-----','-----END CERTIFICATE-----'], ['',''], $sm2base64CertData);
//        $sm2Base64SourceData = base64_encode($data);
//        $ret = lajp_call("cfca.sadk2.api.EnvelopeKitSm2::envelopeMessageSm2", $sm2Base64SourceData, $sm2signAlg, $sm2base64CertData);
//        $arr = json_decode($ret);
//        return $arr->Base64EnvelopeMessage;

        $sm2base64CertData = file_get_contents(self::$SM2EncPublicKeyFilePath);
        $sm2base64CertData = str_replace(['-----BEGIN CERTIFICATE-----','-----END CERTIFICATE-----'], ['',''], $sm2base64CertData);
        $sm2Base64SourceData = base64_encode($data);
        $params = [
            'data'    => $sm2Base64SourceData,
            'prikey'  => $sm2base64CertData,
            'signalg' => 'SM4/ECB/PKCS7Padding'
        ];

        $ret = self::getSign('http://cmbc_union.wftpay.cn/get_context_data.php', $params);
        $signArr = json_decode($ret);
        if (isset($signArr->Base64EnvelopeMessage)) {
            return $signArr->Base64EnvelopeMessage;
        }
        return '';


    }

    public static function Sm2Decrypt($data)
    {
//        $password = self::$SM2EncPrivateKeyFilePassword;
//        $priKey = self::$SM2EncPrivateKeyFilePath;
//        $ret = lajp_call("cfca.sadk2.api.EnvelopeKitSm2::openEvelopedMessageSm2", $data, $priKey, $password);
//        $arr = json_decode($ret, true);
//        return isset($arr['Base64SourceString']) ? base64_decode($arr['Base64SourceString']) : NULL;

        $params = [
            'data'    => $data,
            'prikey'  => '../mechant_sign_sm2.sm2',
            'p12pwd'  => self::$SM2EncPrivateKeyFilePassword
        ];
        $ret = self::getSign('http://cmbc_union.wftpay.cn/decrypt_context_data.php', $params);
        $arr = json_decode($ret, true);
        return isset($arr['Base64SourceString']) ? base64_decode($arr['Base64SourceString']) : NULL;

    }


    public static function verifySign($body, $sign)
    {
        $signAlg = 'SHA256withRSAEncryption';
        $sign_content = self::getSignContent($body);
        $base64SourceString = base64_encode($sign_content);
        $cer = self::$RsaPublicKeyFilePath;
        $base64SignatureString = base64_encode($sign);
        $ret = lajp_call("cfca.sadk2.api.SignatureKitSm2::P1VerifyMessageRsa", $signAlg, $base64SourceString, $cer, $base64SignatureString);
        $arr = json_decode($ret);
        if(isset($arr->Result) && $arr->Result && $arr->Code == '90000000') {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 拼接参数
     * @param  array $params 源数组参数
     * @return 拼接后的字符串
     */
    public static function getSignContent($params)
    {
        $stringToBeSigned = '';
        foreach($params as $key => $val)
        {
            $stringToBeSigned .= $key . '=' . $val . "&amp;";
        }
        $stringToBeSigned = str_replace("\r\n", "", $stringToBeSigned);
        $stringToBeSigned = htmlspecialchars_decode($stringToBeSigned);
        return $stringToBeSigned;
    }

    public function getTranflow($tranflow, $out_trade_no = '')
    {
        $tranflow = explode('-', $tranflow);
        if ($out_trade_no) {
            DB::table("cmbcunion_orders")->insert([
                'platform_id' => $tranflow[0],
                'mch_id' => $tranflow[1],
                'platform_id' => $tranflow[0],
            ]);
        }
        DB::table("cmbcunion_orders")->where('config_id', '1234')->first();
    }

    /**
     * CURL推送数据
     */
    public  function build($url, $fun)
    {
        $ch = curl_init () ;
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, self::$data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_AUTOREFERER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        $result = curl_exec($ch);
        curl_close($ch);

        Log::channel("cmbc_union")->info($fun."_Request", self::$data);
        $params = [
            'data'    => $result,
            'prikey'  => '../mechant_sign_sm2.sm2',
            'p12pwd'  => self::$SM2EncPrivateKeyFilePassword
        ];
        $ret = self::getSign('http://cmbc_union.wftpay.cn/decrypt_context_data.php', $params);
        $arr = json_decode($ret, true);
        $ret = isset($arr['Base64SourceString']) ? base64_decode($arr['Base64SourceString']) : NULL;

        Log::channel("cmbc_union")->info($fun."_Response", ['ret' => $ret]);
        return $ret;
    }

    public static function getSign ($url, $data)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

        $tmpInfo = curl_exec($curl);     //返回api的json对象
        $a = curl_error($curl);
        if(!empty($a)){

        }
        curl_close($curl);
        return $tmpInfo;
    }


}